package controllers

import (
	"github.com/astaxie/beego"
	"encoding/base64"
	"choujiang/models"
	"strconv"
	"log"
	"time"
	"math/rand"
	"fmt"
)

type ChouJiangController struct {
	beego.Controller
}

func (c *ChouJiangController) Prepare() {
	log.Println(c.GetString("token"))
	log.Println(c.GetSession("openid"))
	if oid := c.GetSession("openid"); oid == nil {
		c.Redirect("/login?url="+base64.StdEncoding.EncodeToString([]byte("http://cj.dhxsc.com"+c.Ctx.Request.RequestURI)), 302)
	}
}

func (c *ChouJiangController) GetPage() {
	id, _ := c.GetInt("Id")
	token := c.GetString("token")
	cacheToken, _ := models.GetCache("devicetoken" + strconv.Itoa(id))
	if id == 0 || token == "" || token != cacheToken {
		log.Println("bad guy!:", c.GetSession("openid").(string))
		Message(&c.Controller, ``, "您扫描的二维码已过期，请重新扫描", "", false)
	}
	device := models.Devices{Id: id}
	if err := models.DeviceGetInfo(&device); err != nil {
		Message(&c.Controller, ``, "系统错误,无该设备！", "", false)
	}
	user := models.Users{WxOpenId: c.GetSession("openid").(string)}
	if err := models.UsersGetInfoByWxOpenid(&user); err != nil {
		Message(&c.Controller, ``, "系统错误,无该用户！", "", false)
	}
	if exist, _ := models.GetCacheBool("choujiangId" + strconv.Itoa(user.Id)); exist {
		Message(&c.Controller, ``, "您的抽奖机会已经用完了，请下一个时段尝试！", "", false)
	}

	if device.DeviceType == 1 {
		uid, _ := models.GetCacheInt("deviceuser" + strconv.Itoa(id))
		if uid != 0 {
			Message(&c.Controller, ``, "请等待其他人抽奖结束！", "", false)
		}
		models.PutIntoCache("deviceuser"+strconv.Itoa(id), user.Id, time.Minute)
		go pushToDevice(&device)
		Message(&c.Controller, ``, "请在大屏幕上点击抽奖，奖品稍后将会发送到您的账户！", "", false)
	}
	if device.DeviceType == 2 {
		UserChoujiang(c, &device, &user)
	}
}

func pushToDevice(device *models.Devices) {
	err := sendMessageByUname(strconv.Itoa(device.Id), strconv.Itoa(device.Id))
	log.Println(err)
}

func UserChoujiang(c *ChouJiangController, device *models.Devices, user *models.Users) {
	pointModule := models.PointModule{Id: device.PointModule}
	if err := models.PointModuleGetInfo(&pointModule); err != nil {
		Message(&c.Controller, `/device/qrcode`, "系统错误，获取积分模板错误，请在重新扫码设备端抽奖！", "", false)
	}

	rank, ranktype, point := UserGetResult(c, user, device, &pointModule)
	c.Data["rank"] = rank
	c.Data["ranktype"] = ranktype
	c.Data["pointValue"] = point

	c.Data["point"] = &pointModule
	c.Data["devicetype"] = device.DeviceType
	c.Data["deviceId"] = device.Id
	c.Data["user"] = &user
	c.TplName = "choujiang_user.html"
}

func UserGetResult(c *ChouJiangController, user *models.Users, device *models.Devices, pointModule *models.PointModule) (int, int, float32) {

	if device.DeviceType == 1 {
		Json_Message(&c.Controller, 1, "设备类型已经变更，请重新扫码抽奖！")
	}

	rand.Seed(time.Now().UnixNano())
	currentNum := rand.Intn(100000)
	rank := getRank(currentNum, pointModule)
	//get today Counts
	countTotal, count1, count2, count3 := getTodayCounts(strconv.Itoa(device.Id))
	countTotal++

	//check exceed
	if rank == 1 {
		if count1 >= pointModule.MaxCount1 {
			for {
				rand.Seed(time.Now().UnixNano())
				currentNum := rand.Intn(100000)
				rank = getRank(currentNum, pointModule)
				if rank != 1 {
					break
				}
			}
		}
	} else {
		count1++
	}
	if rank == 2 {
		if count2 >= pointModule.MaxCount2 {
			for {
				rand.Seed(time.Now().UnixNano())
				currentNum := rand.Intn(100000)
				rank = getRank(currentNum, pointModule)
				if rank != 2 {
					break
				}
			}
		}
	} else {
		count2++
	}
	if rank == 3 {
		if count3 >= pointModule.MaxCount3 {
			for {
				rand.Seed(time.Now().UnixNano())
				currentNum := rand.Intn(100000)
				rank = getRank(currentNum, pointModule)
				if rank != 3 {
					break
				}
			}
		}
	} else {
		count3++
	}
	repeatTimes := 10
	//check min
	if rank != 1 && rank != 2 && rank != 3 {
		originrank := rank
		if countTotal >= pointModule.MaxCount1 && count1 < pointModule.MinCount1 {
			i := 0
			for {
				rand.Seed(time.Now().UnixNano())
				currentNum := rand.Intn(100000)
				rank = getRank(currentNum, pointModule)
				if rank != 1 {
					rank = originrank
				}
				if i == repeatTimes || rank == 1 {
					if rank == 1 {
						count3++
					}
					break
				}
				i++
			}
		}
	}

	if rank != 1 && rank != 2 && rank != 3 {
		originrank := rank
		if countTotal >= pointModule.MaxCount2 && count2 < pointModule.MinCount2 {
			i := 0
			for {
				rand.Seed(time.Now().UnixNano())
				currentNum := rand.Intn(100000)
				rank = getRank(currentNum, pointModule)
				if rank != 2 {
					rank = originrank
				}
				if i == repeatTimes || rank == 2 {
					if rank == 2 {
						count2++
					}
					break
				}
				i++
			}
		}
	}

	if rank != 1 && rank != 2 && rank != 3 {
		originrank := rank
		if countTotal >= pointModule.MaxCount3 && count3 < pointModule.MinCount3 {
			i := 0
			for {
				rand.Seed(time.Now().UnixNano())
				currentNum := rand.Intn(100000)
				rank = getRank(currentNum, pointModule)
				if rank != 3 {
					rank = originrank
				}
				if i == repeatTimes || rank == 3 {
					if rank == 3 {
						count3++
					}
					break
				}
				i++
			}
		}
	}
	models.PutIntoCache("UserPriseResult"+strconv.Itoa(user.Id), rank, time.Minute)
	models.PutIntoCache("userDeviceId"+strconv.Itoa(user.Id), device.Id, time.Minute)
	ranktype, point := getRankTypeAndPoint(rank, pointModule)
	return rank, ranktype, point
}

func (c *ChouJiangController) GetPriseResult() {
	user := models.Users{WxOpenId: c.GetSession("openid").(string)}
	if err := models.UsersGetInfoByWxOpenid(&user); err != nil {
		Message(&c.Controller, ``, "系统错误,无该用户！", "", false)
	}
	deviceId, _ := models.GetCacheInt("userDeviceId" + strconv.Itoa(user.Id))
	device := models.Devices{Id: deviceId}
	if err := models.DeviceGetInfo(&device); err != nil {
		Json_Message(&c.Controller, 1, "获取设备信息失败！"+err.Error())
	}
	pointModule := models.PointModule{Id: device.PointModule}
	if err := models.PointModuleGetInfo(&pointModule); err != nil {
		Json_Message(&c.Controller, 1, "获取模板信息失败！"+err.Error())
	}
	rank, _ := models.GetCacheInt("UserPriseResult" + strconv.Itoa(user.Id))
	if rank == 0 {
		models.DeleteCache("UserPriseResult" + strconv.Itoa(user.Id))
		models.DeleteCache("userDeviceId" + strconv.Itoa(user.Id))
		Json_Message(&c.Controller, 1, "系统错误，请重新扫码抽奖!")
	}

	rankFrontPage, _ := c.GetInt("rankFrontPage")
	if rankFrontPage != rank {
		models.DeleteCache("UserPriseResult" + strconv.Itoa(user.Id))
		models.DeleteCache("userDeviceId" + strconv.Itoa(user.Id))
		Json_Message(&c.Controller, 1, "系统错误，请重新扫码抽奖!")
	}

	countTotal, count1, count2, count3 := getTodayCounts(strconv.Itoa(device.Id))
	countTotal++

	switch rank {
	case 1:
		count1++
		addCounts(device.Id,rank)
		break
	case 2:
		count2++
		addCounts(device.Id,rank)
		break
	case 3:
		count3++
		addCounts(device.Id,rank)
		break
	default:
		break
	}
	if ranktype, point := getRankTypeAndPoint(rank, &pointModule); ranktype == 0 {
		go SendPoint(int(point), device, user)
	} else {
		go SendMoney(point, device, user)
	}
	Json_Message(&c.Controller, 0, rank)
}

func (c *ChouJiangController) GetUserinfo() {
	user := models.Users{WxOpenId: c.GetSession("openid").(string)}
	if err := models.UsersGetInfoByWxOpenid(&user); err != nil {
		Message(&c.Controller, "", "获取用户信息错误", "", false)
	}
	c.Data["user"] = &user
	//todo   (some user info list)
	c.TplName = "getmark.html"
}

func (c *ChouJiangController) TradePoint() {
	revId, _ := c.GetInt("revId")
	point, _ := c.GetInt64("point")
	userRev := models.Users{Id: revId}
	currentUser := models.Users{WxOpenId: c.GetSession("openid").(string)}
	if err := models.UsersGetInfo(&userRev); err != nil {
		Message(&c.Controller, "", "接收用户Id异常，无法查找到该用户", "", false)
	}
	if err := models.UsersGetInfoByWxOpenid(&currentUser); err != nil {
		Message(&c.Controller, "", "当前Id异常，无法查找到该用户", "", false)
	}
	if revId == currentUser.Id {
		Message(&c.Controller, "", "您不能讲积分转给自己", "", false)
	}
	if userRev.UserType == 0 {
		Message(&c.Controller, "", "目前不支持普通用户之间的积分交换", "", false)
	}
	if point == 0 {
		point = currentUser.UserCurrentPoint
	}
	c.Data["point"] = point
	c.Data["revId"] = revId
	c.Data["revName"] = userRev.UserName
	c.TplName = "trade.html"

}

func (c *ChouJiangController) Trade() {
	revId, _ := c.GetInt("revId")
	userRev := models.Users{Id: revId}
	point, _ := c.GetInt64("point")
	currentUser := models.Users{WxOpenId: c.GetSession("openid").(string)}
	if err := models.UsersGetInfo(&userRev); err != nil {
		Message(&c.Controller, "", "接收用户Id异常，无法查找到该用户", "", false)
	}
	if err := models.UsersGetInfoByWxOpenid(&currentUser); err != nil {
		Message(&c.Controller, "", "当前Id异常，无法查找到该用户", "", false)
	}
	if revId == currentUser.Id {
		Message(&c.Controller, "", "您不能讲积分转给自己", "", false)
	}
	if userRev.UserType == 0 {
		Message(&c.Controller, "", "目前不支持用户之间的积分交换", "", false)
	}
	if point == 0 {
		point = currentUser.UserCurrentPoint
	}

	str := ""
	switch userRev.UserType {
	case 1:
		str = "商家"
	case 10:
		str = "服务台"
	case 100:
		str = "总服务台"
	default:
		str = "未知类型用户"
	}
	tradeNow(int(point), &currentUser, &userRev)
	Message(&c.Controller, "", fmt.Sprintf("您已在%s（%s）消费%d积分，如有错误，请联系客服！", str, userRev.UserName, point), "", false)
}

func tradeNow(point int, currentUser *models.Users, revUser *models.Users) {
	//point := int(currentUser.UserCurrentPoint)
	if err := models.UserCurrentPointUpdate(currentUser, -point); err != nil {
		log.Fatalln("error when trade point, current user", currentUser.Id, point)
	}
	if err := models.UserCurrentPointUpdate(revUser, point); err != nil {
		log.Fatalln("error when trade point, rev user", revUser.Id, point)
	}
	if err := models.UserTotalPointUpdate(revUser, point); err != nil {
		log.Fatalln("error when trade point, rev user total", revUser.Id, point)
	}
	commitType := 0
	if revUser.UserType == 10 {
		commitType = 1
	} else if revUser.UserType == 100 {
		commitType = 2
	}
	if err := models.PointCommitInsert(&models.PointCommit{Point: point, FromUser: currentUser.Id, ToUser: revUser.Id, CommitType: commitType, CommitTime: time.Now(), Addition: revUser.UserName}); err != nil {
		log.Fatalln("error when insert pointcommit", currentUser.Id, revUser.Id)
	}
	//todo wxpush (two message)
	sqlLogs := models.SQLLogs{UserId: revUser.Id, Body: "积分到账！" + "用户" + strconv.Itoa(currentUser.Id) + "向用户" + strconv.Itoa(revUser.Id) + "转入" + strconv.FormatInt(revUser.UserCurrentPoint, 10) + "积分", LogType: 3}
	models.SQLLogsInsert(&sqlLogs)
	go SendToWX_jifendaozhang(revUser.WxOpenId, "收到用户("+currentUser.WxToken+")积分", strconv.Itoa(point), time.Now().Format("2006-01-02 15:04:05"), "当前积分为："+strconv.FormatInt(revUser.UserCurrentPoint, 10), "", "", []string{revUser.WxOpenId}, "pWDc-LpD50jOglNEmlSzIbUuSlO7Cucn_jFeeYyBNAA")
	go SendToWX_jifendaozhang(currentUser.WxOpenId, "在商家("+revUser.UserName+")消费积分", strconv.Itoa(point), time.Now().Format("2006-01-02 15:04:05"), "当前积分为："+strconv.FormatInt(currentUser.UserCurrentPoint, 10), "", "", []string{currentUser.WxOpenId}, "pWDc-LpD50jOglNEmlSzIbUuSlO7Cucn_jFeeYyBNAA")
}

func (c *ChouJiangController) GetTradeQrCode() {
	currentUser := models.Users{WxOpenId: c.GetSession("openid").(string)}
	if err := models.UsersGetInfoByWxOpenid(&currentUser); err != nil {
		Message(&c.Controller, "", "当前Id异常，无法查找到该用户", "", false)
	}
	c.Data["revId"] = currentUser.Id
	c.TplName = "tradeqrcode.html"
}
